﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleScript
{
    internal class Interpreter
    {
        public List<Statement> StatementList { set; get; }
        public int Position { set; get; }
        public Interpreter(List<Statement> statementList)
        {
            StatementList = statementList;
            Position = 0;
        }

        public Dictionary<string, object> Dictionary = new();
        public LexicalType LexicalType { set; get; }

        public void Execution(Statement statement)
        {
            //字面量，打印操作
            if (statement is Literal literal)
            {
                Console.WriteLine(literal.ToString());
            }
            //标识符，打印操作
            else if (statement is Identifier identifier)
            {
                Console.WriteLine(identifier.ToString());
            }
            //表达式
            else if (statement is Expression expression && expression.Result != null)
            {
                //赋值
                if (expression.OperatorList.Count == 0)
                {
                    Token token = expression.OperandList.First();
                    if (token.LexicalType >= LexicalType.LInt && token.LexicalType <= LexicalType.LString)
                    {
                        switch (token.LexicalType)
                        {
                            case LexicalType.LInt:
                                Dictionary[expression.Result.Literal] = Convert.ToInt32(token.Literal);
                                break;
                            case LexicalType.LFloat:
                                Dictionary[expression.Result.Literal] = Convert.ToSingle(token.Literal);
                                break;
                            case LexicalType.LString:
                                Dictionary[expression.Result.Literal] = token.Literal;
                                break;
                        }
                    }
                    else
                    {
                        Dictionary[expression.Result.Literal] = Dictionary[token.Literal];
                    }
                }
                //运算
                else if (expression.OperatorList.Count == 1)
                {
                    Token first = expression.OperandList[0];
                    Token second = expression.OperandList[1];
                    string one = "";
                    string two = "";
                    if (first.LexicalType == LexicalType.Identifier)
                    {
                        one = Dictionary[first.Literal] + "";
                    }
                    else
                    {
                        one = first.Literal;
                    }
                    if (second.LexicalType == LexicalType.Identifier)
                    {
                        two = Dictionary[second.Literal] + "";
                    }
                    else
                    {
                        two = second.Literal;
                    }
                    if (expression.OperatorList.First().LexicalType == LexicalType.Add)
                    {
                        if (first.LexicalType == LexicalType.LString || second.LexicalType == LexicalType.LString)
                        {
                            Dictionary[expression.Result.Literal] = one + two;
                        }
                        else if (first.LexicalType == LexicalType.LFloat || second.LexicalType == LexicalType.LFloat)
                        {
                            Dictionary[expression.Result.Literal] = Convert.ToSingle(Dictionary[first.Literal].ToString()) + Convert.ToSingle(Dictionary[second.Literal].ToString());
                        }
                        else
                        {
                            if (one.IndexOf(".") != -1 || two.IndexOf(".") != -1)
                            {
                                Dictionary[expression.Result.Literal] = Convert.ToSingle(one) + Convert.ToSingle(two);
                            }
                            else
                            {
                                Dictionary[expression.Result.Literal] = Convert.ToInt32(one) + Convert.ToInt32(two);
                            }
                        }
                    }
                    else
                    {
                        if (first.LexicalType == LexicalType.LString || second.LexicalType == LexicalType.LString)
                        {
                            throw new Exception($"字符串不支持这种运算[{expression.OperatorList[0].LexicalType}]");
                        }
                        if (expression.OperatorList[0].LexicalType == LexicalType.Sub)
                        {
                            if (first.LexicalType == LexicalType.LFloat || second.LexicalType == LexicalType.LFloat)
                            {
                                Dictionary[expression.Result.Literal] = Convert.ToSingle(Dictionary[first.Literal].ToString()) - Convert.ToSingle(Dictionary[second.Literal].ToString());
                            }
                            else
                            {
                                if (one.IndexOf(".") != -1 || two.IndexOf(".") != -1)
                                {
                                    Dictionary[expression.Result.Literal] = Convert.ToSingle(one) - Convert.ToSingle(two);
                                }
                                else
                                {
                                    Dictionary[expression.Result.Literal] = Convert.ToInt32(one) - Convert.ToInt32(two);
                                }
                            }
                        }
                        else if (expression.OperatorList[0].LexicalType == LexicalType.Mul)
                        {
                            if (first.LexicalType == LexicalType.LFloat || second.LexicalType == LexicalType.LFloat)
                            {
                                Dictionary[expression.Result.Literal] = Convert.ToSingle(Dictionary[first.Literal].ToString()) * Convert.ToSingle(Dictionary[second.Literal].ToString());
                            }
                            else
                            {
                                if (one.IndexOf(".") != -1 || two.IndexOf(".") != -1)
                                {
                                    Dictionary[expression.Result.Literal] = Convert.ToSingle(one) * Convert.ToSingle(two);
                                }
                                else
                                {
                                    Dictionary[expression.Result.Literal] = Convert.ToInt32(one) * Convert.ToInt32(two);
                                }
                            }
                        }
                        else if (expression.OperatorList[0].LexicalType == LexicalType.Div)
                        {
                            if (first.LexicalType == LexicalType.LFloat || second.LexicalType == LexicalType.LFloat)
                            {
                                Dictionary[expression.Result.Literal] = Convert.ToSingle(Dictionary[first.Literal].ToString()) / Convert.ToSingle(Dictionary[second.Literal].ToString());
                            }
                            else
                            {
                                if (one.IndexOf(".") != -1 || two.IndexOf(".") != -1)
                                {
                                    Dictionary[expression.Result.Literal] = Convert.ToSingle(one) / Convert.ToSingle(two);
                                }
                                else
                                {
                                    Dictionary[expression.Result.Literal] = Convert.ToInt32(one) / Convert.ToInt32(two);
                                }
                            }
                        }
                        else if (expression.OperatorList[0].LexicalType == LexicalType.Mod)
                        {
                            if (first.LexicalType == LexicalType.LFloat || second.LexicalType == LexicalType.LFloat)
                            {
                                throw new Exception("小数不支持求余运算");
                            }
                            else
                            {
                                if (one.IndexOf(".") != -1 || two.IndexOf(".") != -1)
                                {
                                    throw new Exception("小数不支持求余运算");
                                }
                                else
                                {
                                    Dictionary[expression.Result.Literal] = Convert.ToInt32(one) % Convert.ToInt32(two);
                                }
                            }
                        }
                        else
                        {
                            throw new Exception($"不支持的运算符[{expression.OperatorList[0].LexicalType}]");
                        }
                    }
                }
                else
                {
                    throw new Exception("不支持多个操作数的运算");
                }
            }
            else if (statement is Call call && call.Function != null)
            {
                switch (call.Function.LexicalType)
                {
                    case LexicalType.Input:
                        string? input = Console.ReadLine();
                        if (input != null)
                        {
                            Dictionary["temp"] = input;
                            Dictionary["临变"] = Dictionary["temp"];
                        }
                        break;
                    case LexicalType.Output:
                        if (call.ParameterList[0].LexicalType == LexicalType.Identifier)
                        {
                            Console.WriteLine(Dictionary[call.ParameterList[0].Literal]);
                        }
                        else
                        {
                            Console.WriteLine(call.ParameterList[0].Literal);
                        }
                        break;
                    case LexicalType.Int:
                        Dictionary["temp"] = Convert.ToInt32(Dictionary[call.ParameterList[0].Literal]);
                        Dictionary["临变"] = Dictionary["temp"];
                        break;
                    case LexicalType.Float:
                        Dictionary["temp"] = Convert.ToSingle(Dictionary[call.ParameterList[0].Literal]);
                        Dictionary["临变"] = Dictionary["temp"];
                        break;
                    case LexicalType.String:
                        string? s = Dictionary[call.ParameterList[0].Literal].ToString();
                        Dictionary["temp"] = s ?? "";
                        Dictionary["临变"] = Dictionary["temp"];
                        break;
                }
            }
            else
            {
                throw new Exception("不支持的语法结构");
            }
        }
    }
}
